/*
Abstract:
  Localization layer support

Last changed:
  $Id: symbol_check.h 82 2009-12-08 20:53:44Z vitamin.caig $

Author:
  (C) Vitamin/CAIG/2001

  This file is the part of Textator project
*/
#ifndef __SYMBOL_CHECK_H_DEFINED__
#define __SYMBOL_CHECK_H_DEFINED__

#include "types.h"

#include <cctype>

namespace Symbol
{
  inline bool IsLabel(String::value_type sym)
  {
    return 0 != std::isalpha(sym) || 0 != std::isdigit(sym) || '_' == sym;
  }

  inline bool IsKey(String::value_type sym)
  {
    return IsLabel(sym);
  }

  inline bool IsEscaped(String::value_type sym)
  {
    return 0 != std::iscntrl(sym);
  }

  inline bool IsAlpha(String::value_type sym)
  {
    return 0 != std::isalpha(sym);
  }

  inline bool IsSpace(String::value_type sym)
  {
    return 0 != std::isspace(sym);
  }

  inline bool IsLineEnd(String::value_type sym)
  {
    return '\r' == sym || '\n' == sym;
  }

  inline bool IsDigit(String::value_type sym)
  {
    return 0 != std::isdigit(sym);
  }

  inline bool IsPrintable(String::value_type sym)
  {
    return 0 != std::isprint(sym);
  }

  struct EscapePair
  {
    String::value_type Symbol;
    String::value_type Escapee;
  };

  template<std::size_t D>
  inline bool Escape(String::value_type sym, const EscapePair (&arr)[D], String::value_type& res)
  {
    for (const EscapePair* eptr = arr, *lim = arr + D; eptr != lim; ++eptr)
    {
      if (eptr->Symbol == sym)
      {
        res = eptr->Escapee;
        return true;
      }
    }
    return false;
  }

  template<std::size_t D>
  inline bool Unescape(String::value_type sym, const EscapePair (&arr)[D], String::value_type& res)
  {
    for (const EscapePair* eptr = arr, *lim = arr + D; eptr != lim; ++eptr)
    {
      if (eptr->Escapee == sym)
      {
        res = eptr->Symbol;
        return true;
      }
    }
    return false;
  }
}

#endif //__SYMBOL_CHECK_H_DEFINED__
